
import grpc
import asyncio
from services.user import UserService
from services.address import AddressServicer

from protos import user_pb2_grpc,address_pb2_grpc
from services.interceptors import UserInterceptor
import consul
import uuid
from typing import Tuple
import socket
from loguru import logger

client=consul.Consul(host='localhost',port=8500)

def get_ip_port() -> Tuple[str, int]:
    sock_ip=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock_ip.connect(("8.8.8.8", 80))
    ip = sock_ip.getsockname()[0]

    sock_ip.close()
    socket_port=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    socket_port.bind(("0.0.0.0", 0))
    port = socket_port.getsockname()[1]
    socket_port.close()
    return ip, port

def regiser_consul(ip:str,port:int):
    service_id=str(uuid.uuid4().hex)
    client.agent.service.register(
        name='user_service',
        service_id=service_id,
        address=ip,
        port=port,
        tags=['user','grpc'],
        check=consul.Check().tcp(ip, port, '30s'),
    )
    return service_id

def deregisiter_consul(service_id:str):
    client.agent.service.deregister(service_id)
    
async def main():
    server = grpc.aio.server(interceptors=[UserInterceptor()])
    user_pb2_grpc.add_UserServicer_to_server(UserService(), server)
    address_pb2_grpc.add_AddressServicer_to_server(AddressServicer(), server)
    ip,port=get_ip_port()
    server.add_insecure_port(f"[::]:{port}")
    service_id=regiser_consul(ip,port)
    await server.start()
    logger.info(f"gRPC服务器启动了，牛逼了 端口:0.0.0.0:{port} 启动成功")
    try:
        await server.wait_for_termination()
    except Exception as e:
        print(f"gRPC服务器关闭失败: {e}")
    finally:
        # 确保在任何情况下都尝试注销服务
        try:
            deregisiter_consul(service_id)
            print(f"consul 成功把 服务 {service_id} 注销了，端口 {port}")
        except Exception as e:
            print(f"consul注销gRPC服务器失败: {e}")   
        # 确保在任何情况下都尝试停止服务器
        try:
            # 使用同步方式停止服务器以避免CancelledError
            await server.stop(None)
            print(f"gRPC服务器停止成功，端口 {port}")
        except Exception as e:
            print(f"gRPC服务器停止失败: {e}")
        print(f"gRPC服务器注销了，端口 {port} 注销成功")
    
if __name__ == "__main__":
    asyncio.run(main())
